package com.fulihui.wgj.schedule.job;

import com.alibaba.dubbo.config.annotation.Reference;
import com.fulihui.common.util.PlatformUtil;
import com.fulihui.weixinsdk.WeixinSDK;
import com.fulihui.weixinsdk.model.UserSummaryData;
import com.fulihui.weixinsdk.request.statistics.UserSummaryRequest;
import com.fulihui.weixinsdk.result.statistics.UserSummaryResult;
import com.fulihui.wgj.facade.dto.WxPlatformDTO;
import com.fulihui.wgj.facade.dto.WxSubscribeStatisticsDTO;
import com.fulihui.wgj.facade.request.statistics.WxSubscribeStatisticsQueryRequest;
import com.fulihui.wgj.facade.request.statistics.WxSubscribeStatisticsRequest;
import com.fulihui.wgj.facade.service.platform.WxPlatformService;
import com.fulihui.wgj.facade.service.statistics.WxSubscribeStatisticsService;
import com.fulihui.wgj.schedule.annotation.MutexLock;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author: LiuJie
 * @version: 2018/7/7 10:21
 * @description: 公众号关注、取关人数统计
 */
@Component
@Slf4j
public class SubscribeStatticsJob {

    @Reference(version = "1.0.0")
    private WxSubscribeStatisticsService subscribeStatisticsService;
    @Reference(version = "1.0.0")
    private WxPlatformService wxPlatformService;
    @Autowired
    private PlatformUtil platformUtil;
    @Autowired
    private WeixinSDK weixinSDK;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    @MutexLock(node = "${job.node.subscribeStatistics_execute}")
    @Scheduled(cron = "${job.cron.subscribeStatistics_execute}")
    public void excute(){

        log.info("公众号关注、取关人数统计，开始。");

        // 获取所有有效公众号
        List<WxPlatformDTO> platformList = wxPlatformService.queryUsefulPlatform().getData();
        if(CollectionUtils.isEmpty(platformList)){
            log.info("platform list is empty, job over！");
            return;
        }
        // 查询上一天
        String queryDate = sdf.format(DateUtils.addDays(new Date(), -1));
        // 累积需要知道上上一天的累计数
        String beforeDate = sdf.format(DateUtils.addDays(new Date(), -2));
        for (WxPlatformDTO wxPlatformDTO : platformList) {

            String appid = wxPlatformDTO.getAppId();
            WxSubscribeStatisticsRequest request = getNewAndCancel(appid, queryDate);
            if(null == request){
                continue;
            }
            // 存入累积用户数据
            request.setCumulateUser(getCumulate(appid,beforeDate,request.getNewUser()));
            // 入库
            subscribeStatisticsService.saveWxStatistics(request);
        }
        log.info("公众号关注、取关人数统计，结束。");
    }

    /**
     * wx SDK 请求 appid 取关、关注数
     * @param appid
     * @param queryDate
     * @return
     */
    private WxSubscribeStatisticsRequest getNewAndCancel(String appid, String queryDate){
        String accessToken = platformUtil.get(appid);
        if(StringUtils.isBlank(accessToken)) {
            log.error("accessToken未找到，appid = {},queryDate = {},获取 取关、关注人数失败！",appid,queryDate);
            return null;
        }
        UserSummaryRequest summaryRequest = new UserSummaryRequest();
        summaryRequest.setAccess_token(accessToken);
        summaryRequest.setBegin_date(queryDate);
        summaryRequest.setEnd_date(queryDate);
        UserSummaryResult userSummaryResult = weixinSDK.invokeService(summaryRequest);

        WxSubscribeStatisticsRequest request = new WxSubscribeStatisticsRequest();
        request.setAppId(appid);
        request.setRefDate(queryDate);

        if (userSummaryResult == null
                || CollectionUtils.isEmpty(userSummaryResult.getList())) {
            log.error("微信SDK返回数据为空，appid = {},request = {},当天没有关注、取关人数！！",appid,summaryRequest);
            request.setCancelUser("0");
            request.setNewUser("0");
            request.setNetGrowth("0");
            return request;
        }

        int newUserSum = 0,cancelUserSum =0;
        // 累加所有渠道的新增和取关
        for (UserSummaryData summaryData : userSummaryResult.getList()) {
            if(null == summaryData){
                continue;
            }
            String new_user = summaryData.getNew_user();
            String cancel_user = summaryData.getCancel_user();
            if(StringUtils.isNotBlank(new_user) && NumberUtils.isParsable(new_user)){
                newUserSum += Integer.parseInt(new_user);
            }
            if(StringUtils.isNotBlank(cancel_user) && NumberUtils.isParsable(cancel_user)){
                cancelUserSum += Integer.parseInt(cancel_user);
            }
        }
        request.setCancelUser(String.valueOf(cancelUserSum));
        request.setNewUser(String.valueOf(newUserSum));
        request.setNetGrowth(String.valueOf(newUserSum - cancelUserSum));
        return request;
    }



    /**
     * 累积关注
     * @param appid
     * @param queryDate 查询日期 （上一天）
     * @param todayNew 今天新增
     * @return
     */
    private String getCumulate(String appid,String queryDate,String todayNew){
        Integer sum = 0;
        if(StringUtils.isNotBlank(todayNew) && NumberUtils.isParsable(todayNew)){
            sum = Integer.parseInt(todayNew);
        }
        WxSubscribeStatisticsQueryRequest request = new WxSubscribeStatisticsQueryRequest();
        request.setAppId(appid);
        request.setBeginDate(queryDate);
        request.setEndDate(queryDate);
        List<WxSubscribeStatisticsDTO> data = subscribeStatisticsService.queryWxStatistics(request).getData();
        if(CollectionUtils.isEmpty(data)){
            log.error("未查询到用户历史累计信息,{}",request);
            return sum.toString();
        }
        //只会有一条，get 用户累积信息
        String cumulateUser = data.get(0).getCumulateUser();
        if(StringUtils.isNotBlank(cumulateUser) && NumberUtils.isParsable(cumulateUser)){
            sum += Integer.parseInt(cumulateUser);
        }
        return sum.toString();
    }

}
